import os
import functools
import gzip
import math
import json
import anndata
import scipy.io
import scipy.sparse
import pandas as pd
import scanpy as sc
import numpy as np
import scrublet
import sklearn.cluster
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
from plotnine import *
theme_set(theme_classic() + theme(panel_grid_major=element_line()))
rules = {
"frac_mito": (0, 0.1),
"counts": (1000, 20000),
"genes": (70, 6000),
}
celltype_map = {
"neuron": ["Rbfox3", "Calb2", "Nefl", "Th"],
"lineage": ["Aqp4", "Egfr", "Mki67", "Dcx"],
"microglia": ["Itgam", "Ptprc"],
"oligo": ["Cldn11"],
"oec": ["Apod"],
"pericyte": ["Foxd1", "Colec12"],
"opc": ["Olig1", "Olig2", "Lhfpl3", "Cntn1"],
"endothelial": ["Prom1", "Cldn5", "Pecam1"],
"ependymal": ["Cald1", "Sod3"],
}
hto_order = ["SVZ1", "SVZ2", "ROB1", "ROB2", "Unclear"]
d = sc.read("data/ifnagrko_raw.h5ad")
d.var_names_make_unique()
d
AnnData object with n_obs × n_vars = 844265 × 32287
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped'
var: 'gene_id'
obsm: 'hto'
layers: 'spliced', 'unspliced'
sc.pp.filter_cells(d, min_counts=100)
sc.pp.filter_genes(d, min_cells=3)
d
AnnData object with n_obs × n_vars = 99768 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts'
var: 'gene_id', 'n_cells'
obsm: 'hto'
layers: 'spliced', 'unspliced'
d.var["mt"] = d.var_names.str.startswith("mt-")
d.obs["counts"] = d.X.sum(axis=1).A1
d.obs["genes"] = (d.X > 0).sum(axis=1).A1
d.obs["counts_mito"] = d[:,d.var.mt].X.sum(axis=1).A1
d.obs["frac_mito"] = d.obs["counts_mito"] / d.obs["counts"]
d
AnnData object with n_obs × n_vars = 99768 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito'
var: 'gene_id', 'n_cells', 'mt'
obsm: 'hto'
layers: 'spliced', 'unspliced'
scrub = scrublet.Scrublet(d.X)
d.obs["scrub_score"], d.obs["scrub_label"] = scrub.scrub_doublets()
d
Preprocessing... Simulating doublets... Embedding transcriptomes using PCA... Calculating doublet scores... Automatically set threshold at doublet score = 0.40 Detected doublet rate = 0.1% Estimated detectable doublet fraction = 0.7% Overall doublet rate: Expected = 10.0% Estimated = 18.6% Elapsed time: 309.1 seconds
AnnData object with n_obs × n_vars = 99768 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito', 'scrub_score', 'scrub_label'
var: 'gene_id', 'n_cells', 'mt'
obsm: 'hto'
layers: 'spliced', 'unspliced'
exclusions = {key: ~d.obs[key].between(*rules[key], inclusive=True) for key in ["frac_mito", "counts", "genes"]}
exclusions["scrublet"] = d.obs.scrub_label
d.obs["exclude"] = functools.reduce(lambda a, b: a | b, exclusions.values())
d.obs.exclude.value_counts()
True 81466 False 18302 Name: exclude, dtype: int64
d = d[~d.obs.exclude,:]
d
View of AnnData object with n_obs × n_vars = 18302 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito', 'scrub_score', 'scrub_label', 'exclude'
var: 'gene_id', 'n_cells', 'mt'
obsm: 'hto'
layers: 'spliced', 'unspliced'
d.layers["raw_counts"] = d.X.copy()
sc.pp.normalize_total(d, target_sum=1e4)
sc.pp.log1p(d)
d.layers["lognormal"] = d.X.copy()
d
AnnData object with n_obs × n_vars = 18302 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito', 'scrub_score', 'scrub_label', 'exclude'
var: 'gene_id', 'n_cells', 'mt'
uns: 'log1p'
obsm: 'hto'
layers: 'spliced', 'unspliced', 'raw_counts', 'lognormal'
d.obs["genotype"] = [x.split("-")[1].split("_")[0] for x in d.obs.index]
d.obs["age"] = ["old" if "20mo" in x else "young" for x in d.obs.index]
d.obs.age
barcode
AAACCCAGTCTCCTGT-WT_20mo_2021_001 old
AAACGAAAGGTACTGG-WT_20mo_2021_001 old
AAACGAACATGGCTGC-WT_20mo_2021_001 old
AAACGAAGTAGCTGAG-WT_20mo_2021_001 old
AAACGAATCACCCTCA-WT_20mo_2021_001 old
...
TTTGGTTCATGACTTG-WT_4mo_2021_001 young
TTTGGTTGTTCCTTGC-WT_4mo_2021_001 young
TTTGTTGAGCCGTTAT-WT_4mo_2021_001 young
TTTGTTGCAGATGCGA-WT_4mo_2021_001 young
TTTGTTGTCTGAGCAT-WT_4mo_2021_001 young
Name: age, Length: 18302, dtype: object
{x.split("-")[1].split("_")[1] for x in d.obs.index}
{'20mo', '4mo'}
d.obs.genotype
barcode
AAACCCAGTCTCCTGT-WT_20mo_2021_001 WT
AAACGAAAGGTACTGG-WT_20mo_2021_001 WT
AAACGAACATGGCTGC-WT_20mo_2021_001 WT
AAACGAAGTAGCTGAG-WT_20mo_2021_001 WT
AAACGAATCACCCTCA-WT_20mo_2021_001 WT
..
TTTGGTTCATGACTTG-WT_4mo_2021_001 WT
TTTGGTTGTTCCTTGC-WT_4mo_2021_001 WT
TTTGTTGAGCCGTTAT-WT_4mo_2021_001 WT
TTTGTTGCAGATGCGA-WT_4mo_2021_001 WT
TTTGTTGTCTGAGCAT-WT_4mo_2021_001 WT
Name: genotype, Length: 18302, dtype: object
sc.pp.scale(d, zero_center=False)
sc.tl.pca(d, n_comps=50)
sc.pp.neighbors(d, n_neighbors=15)
sc.tl.umap(d)
d
AnnData object with n_obs × n_vars = 18302 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito', 'scrub_score', 'scrub_label', 'exclude', 'genotype', 'age'
var: 'gene_id', 'n_cells', 'mt', 'mean', 'std'
uns: 'log1p', 'pca', 'neighbors', 'umap'
obsm: 'hto', 'X_pca', 'X_umap'
varm: 'PCs'
layers: 'spliced', 'unspliced', 'raw_counts', 'lognormal'
obsp: 'distances', 'connectivities'
plt.rcParams['figure.figsize'] = [5, 5]
plt.rcParams['figure.dpi'] = 150
sc.pl.umap(d)
... storing 'genotype' as categorical ... storing 'age' as categorical
sc.tl.leiden(d)
d.obs["dbscan"] = sklearn.cluster.DBSCAN().fit_predict(d.obsm["X_umap"]).astype(str)
dbscan_value_counts = d.obs.dbscan.value_counts()
lineage_cluster_id = dbscan_value_counts.index[dbscan_value_counts.argmax()]
d.obs["is_lineage"] = (d.obs.dbscan == lineage_cluster_id)
d
AnnData object with n_obs × n_vars = 18302 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito', 'scrub_score', 'scrub_label', 'exclude', 'genotype', 'age', 'leiden', 'dbscan', 'is_lineage'
var: 'gene_id', 'n_cells', 'mt', 'mean', 'std'
uns: 'log1p', 'pca', 'neighbors', 'umap', 'leiden'
obsm: 'hto', 'X_pca', 'X_umap'
varm: 'PCs'
layers: 'spliced', 'unspliced', 'raw_counts', 'lognormal'
obsp: 'distances', 'connectivities'
plt.rcParams['figure.figsize'] = [3, 3]
plt.rcParams['figure.dpi'] = 150
sc.pl.umap(d, color=["dbscan", "leiden", "Aqp4", "Dcx", "Pecam1", "Cldn5", "Itgam", "Ptprc"], ncols=2)
... storing 'dbscan' as categorical
rob_htos = [h.startswith("ROB") for h in hto_order]
svz_htos = [h.startswith("SVZ") for h in hto_order]
d.obs["rob_sum"] = d.obsm["hto"][:,rob_htos].sum(axis=1)
d.obs["svz_sum"] = d.obsm["hto"][:,svz_htos].sum(axis=1)
d.obs["hto_sum"] = d.obs.rob_sum + d.obs.svz_sum
d.obs["svz_frac"] = d.obs.svz_sum / d.obs.hto_sum
d
AnnData object with n_obs × n_vars = 18302 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito', 'scrub_score', 'scrub_label', 'exclude', 'genotype', 'age', 'leiden', 'dbscan', 'is_lineage', 'rob_sum', 'svz_sum', 'hto_sum', 'svz_frac'
var: 'gene_id', 'n_cells', 'mt', 'mean', 'std'
uns: 'log1p', 'pca', 'neighbors', 'umap', 'leiden', 'dbscan_colors', 'leiden_colors'
obsm: 'hto', 'X_pca', 'X_umap'
varm: 'PCs'
layers: 'spliced', 'unspliced', 'raw_counts', 'lognormal'
obsp: 'distances', 'connectivities'
plt.rcParams['figure.figsize'] = [4, 4]
plt.rcParams['figure.dpi'] = 150
sc.pl.umap(d, color=["svz_frac", "leiden", "dbscan"], color_map=matplotlib.cm.RdBu)
marker_map_tups = functools.reduce(lambda x, y: x+y, [[(key, value) for value in markers] for (key, markers) in celltype_map.items()])
marker_genes = [tup[1] for tup in marker_map_tups]
expr = pd.DataFrame(d[:,marker_genes].X.todense(), index=d.obs.index, columns=pd.MultiIndex.from_tuples(marker_map_tups))
expr = expr.groupby(level=0, axis=1).sum()
mat = d.obs[["dbscan"]].join(expr, how="left").groupby("dbscan").agg("median")
sns.heatmap(mat.divide(mat.sum(axis=1), axis=0))
<AxesSubplot:ylabel='dbscan'>
typemat = (np.max(mat, axis=1) == mat.transpose()).transpose()
sns.heatmap(typemat)
<AxesSubplot:ylabel='dbscan'>
typemap = typemat.apply(lambda d: d.index[d][0], axis=1).to_dict()
typemap["-1"] = "singleton"
typemap
{'0': 'oec',
'1': 'lineage',
'2': 'opc',
'3': 'neuron',
'4': 'oligo',
'5': 'microglia',
'6': 'neuron',
'7': 'endothelial',
'8': 'ependymal',
'9': 'lineage',
'10': 'opc',
'11': 'neuron',
'-1': 'singleton'}
d.obs["celltype1"] = [typemap[i] for i in d.obs.dbscan]
plt.rcParams['figure.figsize'] = [4, 4]
plt.rcParams['figure.dpi'] = 150
sc.pl.umap(d, color=["svz_frac", "celltype1", "dbscan", "leiden"], color_map=matplotlib.cm.RdBu, ncols=2)
... storing 'celltype1' as categorical
leiden:19 and leiden:20 are actually not SVZ cells and thus should not be called lineage.leiden:22 is likely to be further doubletssc.pl.umap(d, color=["scrub_score"])
d.obs.celltype1 = d.obs.celltype1.astype(str)
d.obs.loc[d.obs.leiden=="19", "celltype1"] = "ob astrocyte"
d.obs.loc[d.obs.leiden=="20", "celltype1"] = "ob astrocyte"
d.obs.loc[(d.obs.leiden=="22"), "celltype1"] = "doublet"
sc.pl.umap(d, color=["celltype1"])
... storing 'celltype1' as categorical
dlin = d[d.obs.celltype1 == "lineage"].copy()
dlin.uns["iroot"] = np.argmax(dlin[:,"Aqp4"].X)
sc.tl.pca(dlin)
sc.pp.neighbors(dlin)
sc.tl.diffmap(dlin)
sc.tl.dpt(dlin)
d.obs = d.obs.join(dlin.obs[["dpt_pseudotime"]], how="left")
del dlin
d
AnnData object with n_obs × n_vars = 18302 × 20830
obs: 'batch', 'yfp_count', 'kanr_count', 'SVZ1', 'SVZ2', 'ROB1', 'ROB2', 'unmapped', 'n_counts', 'counts', 'genes', 'counts_mito', 'frac_mito', 'scrub_score', 'scrub_label', 'exclude', 'genotype', 'age', 'leiden', 'dbscan', 'is_lineage', 'rob_sum', 'svz_sum', 'hto_sum', 'svz_frac', 'celltype1', 'dpt_pseudotime'
var: 'gene_id', 'n_cells', 'mt', 'mean', 'std'
uns: 'log1p', 'pca', 'neighbors', 'umap', 'leiden', 'dbscan_colors', 'leiden_colors', 'celltype1_colors'
obsm: 'hto', 'X_pca', 'X_umap'
varm: 'PCs'
layers: 'spliced', 'unspliced', 'raw_counts', 'lognormal'
obsp: 'distances', 'connectivities'
sc.pl.umap(d, color=["dpt_pseudotime"])
markers = ["Aqp4", "Egfr", "Dcx", "Mki67", "Gria1", "S100b"]
bin_count = 100
plt.rcParams['figure.figsize'] = [10, 5]
plt.rcParams['figure.dpi'] = 150
lineage_cells = d.obs.celltype1 == "lineage"
marker_data = pd.DataFrame(d[lineage_cells,markers].layers["lognormal"].todense(), columns=markers, index=d[lineage_cells,:].obs.index).join(d.obs, how="left")
marker_data["bin"] = pd.cut(marker_data.dpt_pseudotime, bins=bin_count)
marker_mat = marker_data.reset_index()[["bin"] + markers].groupby(["bin"]).sum()
sns.heatmap(marker_mat.divide(marker_mat.sum(axis=1), axis=0).transpose())
<AxesSubplot:xlabel='bin'>
cuts = [0.13, 0.31, 0.73, 0.842]
types = pd.DataFrame(
{"lo": [0] + cuts,
"hi": cuts + [1],
"type": ["qNSC1", "qNSC2", "aNSC", "TAP", "NB"]
}
)
types["dpt_pseudotime"] = types.lo + (types.hi-types.lo)/2
marker_mat = marker_data.reset_index()[["bin"] + markers].groupby("bin").sum()
marker_mat = marker_mat.divide(marker_mat.sum(axis=1), axis=0)
marker_mat = marker_mat.reset_index()
marker_mat["dpt_pseudotime"] = [b.mid for b in marker_mat.bin]
gg = (
ggplot(marker_mat.melt(id_vars=["dpt_pseudotime", "bin"]), aes("dpt_pseudotime", "value")) +
geom_bar(aes(fill="variable"), stat="identity", width=1/bin_count) +
geom_vline(xintercept=cuts) +
geom_label(aes(x="dpt_pseudotime", y=.99, label="type"), data=types, size=8.5, va="top", label_r=0, label_size=0) +
coord_cartesian(expand=False) +
labs(y="Relative expression", x="Binned Pseudotime", colour="Gene")
)
ggsave(gg, "plots/celltype_calling.pdf")
ggsave(gg, "plots/celltype_calling.svg")
gg
/home/jooa/.conda/envs/cycleflow/lib/python3.8/site-packages/plotnine/ggplot.py:727: PlotnineWarning: Saving 6.4 x 4.8 in image. /home/jooa/.conda/envs/cycleflow/lib/python3.8/site-packages/plotnine/ggplot.py:730: PlotnineWarning: Filename: plots/celltype_calling.pdf /home/jooa/.conda/envs/cycleflow/lib/python3.8/site-packages/plotnine/ggplot.py:727: PlotnineWarning: Saving 6.4 x 4.8 in image. /home/jooa/.conda/envs/cycleflow/lib/python3.8/site-packages/plotnine/ggplot.py:730: PlotnineWarning: Filename: plots/celltype_calling.svg
<ggplot: (8775825553773)>
ggplot(d.obs, aes("dpt_pseudotime")) + geom_histogram(bins=100) + coord_cartesian(expand=False)
/home/jooa/.conda/envs/cycleflow/lib/python3.8/site-packages/plotnine/layer.py:372: PlotnineWarning: stat_bin : Removed 3873 rows containing non-finite values.
<ggplot: (8775825567495)>
d.obs["celltype2"] = [
np.nan if pd.isna(x) else
"qNSC1" if x < cuts[0] else
"qNSC2" if x < cuts[1] else
"aNSC" if x < cuts[2] else
"TAP" if x < cuts[3] else
"NB"
for x in d.obs.dpt_pseudotime
]
(
ggplot(d.obs.assign(UMAP1 = d.obsm["X_umap"][:,0], UMAP2=d.obsm["X_umap"][:,1]), aes("UMAP1", "UMAP2")) +
geom_point(aes(colour="celltype2"), size=0.1) +
theme_void() +
coord_equal()
)
<ggplot: (8775825537247)>
d.obs["celltype"] = [c1 if pd.isna(c2) else f"{c1}:{c2}" for (c1, c2) in zip(d.obs.celltype1, d.obs.celltype2)]
ddata = d.obs.assign(UMAP1 = d.obsm["X_umap"][:,0], UMAP2=d.obsm["X_umap"][:,1])
(
ggplot(ddata, aes("UMAP1", "UMAP2")) +
geom_point(colour="gray", size=0.1, data=ddata.loc[ddata.celltype1 != "lineage"]) +
geom_point(aes(colour="dpt_pseudotime"), size=0.1, data=ddata.loc[ddata.celltype1 == "lineage"]) +
theme(axis_line=element_blank(), axis_ticks=element_blank(), panel_grid=element_blank(), axis_text=element_blank(), axis_title=element_blank()) +
#theme_void() +
#theme(legend_position="none") +
coord_equal()
)
<ggplot: (8775828156784)>
(
ggplot(ddata, aes("UMAP1", "UMAP2")) +
geom_point(aes(colour="svz_frac"), size=0.1) +
scale_colour_cmap(cmap_name="RdBu") +
theme(axis_line=element_blank(), axis_ticks=element_blank(), panel_grid=element_blank(), axis_text=element_blank(), axis_title=element_blank()) +
#theme_void() +
#theme(legend_position="none") +
coord_equal()
)
<ggplot: (8775815274912)>
dlabel1 = d.obs.assign(UMAP1 = d.obsm["X_umap"][:,0], UMAP2=d.obsm["X_umap"][:,1]).loc[:,["celltype1", "UMAP1", "UMAP2"]].groupby("celltype1").median()
dlabel1 = dlabel1.reset_index().loc[dlabel1.index != "lineage"]
dlabel2 = d.obs.assign(UMAP1 = d.obsm["X_umap"][:,0], UMAP2=d.obsm["X_umap"][:,1]).loc[d.obs.celltype1 == "lineage",["celltype2", "UMAP1", "UMAP2"]].groupby("celltype2").median().reset_index()
(
ggplot(ddata, aes("UMAP1", "UMAP2")) +
geom_point(colour="gray", size=0.1, data=ddata.loc[ddata.celltype1 != "lineage"]) +
geom_point(aes(colour="celltype2"), size=0.1, data=ddata.loc[ddata.celltype1 == "lineage"]) +
geom_label(aes(label="celltype1"), data=dlabel1[dlabel1.UMAP1 > 5], nudge_x=3, nudge_y=1, alpha=0.6) +
geom_label(aes(label="celltype1"), data=dlabel1[dlabel1.UMAP1 < 5], nudge_x=-3, nudge_y=0, alpha=0.6) +
geom_label(aes(label="celltype2", colour="celltype2"), data=dlabel2, nudge_x=0, alpha=1.0) +
theme_void() +
theme(legend_position="none") +
coord_equal()
)
<ggplot: (8775828122567)>
plt.rcParams['figure.figsize'] = [3, 3]
plt.rcParams['figure.dpi'] = 150
sc.pl.umap(d, color=["Pecam1", "Itgam", "Ptprc", "Aqp4", "S100b", "celltype"], ncols=3)
... storing 'celltype2' as categorical ... storing 'celltype' as categorical
d.write_h5ad("computed/ifnagrko.h5ad")
d.obs.celltype.value_counts()
lineage:NB 6910 lineage:qNSC1 4491 oec 2075 lineage:qNSC2 1194 lineage:TAP 1118 lineage:aNSC 716 neuron 673 microglia 343 ob astrocyte 311 oligo 137 doublet 106 endothelial 103 opc 94 ependymal 29 singleton 2 Name: celltype, dtype: int64
columns = ["celltype", "celltype1", "celltype2", "dpt_pseudotime", "svz_frac", "hto_sum", "leiden", "dbscan", "frac_mito", "counts", "genes", "scrub_score", "age", "genotype"]
d.obs[columns].assign(UMAP1=d.obsm["X_umap"][:,0], UMAP2=d.obsm["X_umap"][:,1]).to_csv("computed/ifnagrko_obs.csv")
d.var.reset_index()[["gene_name", "gene_id"]].to_csv("computed/ifnagrko_var.csv")
with gzip.open("computed/ifnagrko_raw_counts.mtx.gz", "wb") as f:
scipy.io.mmwrite(f, d.layers["raw_counts"])
with gzip.open("computed/ifnagrko_log_norm.mtx.gz", "wb") as f:
scipy.io.mmwrite(f, d.layers["lognormal"])
pd.DataFrame(d.obsm["hto"], columns=hto_order, index=d.obs.index).to_csv("computed/hto_counts.csv.gz")
!pip list
Package Version ------------------------- ----------- amply 0.1.4 anndata 0.7.6 anyio 2.2.0 apipkg 1.5 appdirs 1.4.4 argon2-cffi 20.1.0 astroid 2.5.5 async-generator 1.10 attrs 20.3.0 Babel 2.9.0 backcall 0.2.0 bleach 3.3.0 bottle 0.12.19 btrfsutil 5.11.1 CacheControl 0.12.6 cffi 1.14.5 chardet 4.0.0 click 7.1.2 colorama 0.4.4 ConfigArgParse 1.4.1 contextlib2 0.6.0.post1 cryptography 3.4.7 cycleflow 1.0 cycleflow-extra 0.0.1 cycler 0.10.0 Cython 0.29.23 datrie 0.8.2 decorator 4.4.2 defusedxml 0.7.1 deprecation 2.1.0 descartes 1.1.0 distlib 0.3.1 distro 1.5.0 dnspython 1.16.0 docutils 0.17.1 entrypoints 0.3 filelock 3.0.12 future 0.18.2 fuzzywuzzy 0.18.0 get-version 2.2 gitdb 4.0.5 GitPython 3.1.14 Glances 3.1.5 h5py 3.2.1 html5lib 1.1 idna 3.1 importlib-metadata 4.0.1 iniconfig 1.1.1 ipdb 0.13.7 ipykernel 5.5.3 ipython 7.23.0 ipython-genutils 0.2.0 ipywidgets 7.6.3 isort 5.8.0 jedi 0.18.0 Jinja2 2.11.3 joblib 1.0.1 json5 0.9.5 jsonschema 3.2.0 jupyter-client 6.1.12 jupyter-console 6.4.0 jupyter-core 4.7.1 jupyter-packaging 0.7.12 jupyter-resource-usage 0.5.1 jupyter-server 1.4.1 jupyterlab 3.0.10 jupyterlab-execute-time 2.0.2 jupyterlab-git 0.23.3 jupyterlab-latex 2.0.0 jupyterlab-pygments 0.1.2 jupyterlab-server 2.3.0 jupyterlab-system-monitor 0.8.0 jupyterlab-topbar 0.6.1 jupyterlab-vim 0.13.4 kaptan 0.5.12 kb-python 0.26.0 kiwisolver 1.3.1 lazy-object-proxy 1.6.0 legacy-api-wrap 1.2 libtmux 0.8.5 llvmlite 0.36.0 loompy 3.0.6 Markdown 3.3.4 MarkupSafe 1.1.1 matplotlib 3.4.1 matplotlib-inline 0.1.2 mccabe 0.6.1 meson 0.58.0 mistune 0.8.4 mizani 0.7.3 more-itertools 8.7.0 msgpack 1.0.2 natsort 7.1.1 nbclassic 0.2.6 nbclient 0.5.3 nbconvert 6.0.7 nbdime 2.1.0 nbformat 5.1.3 nest-asyncio 1.5.1 networkx 2.5.1 nftables 0.1 notebook 6.3.0 numba 0.53.1 numexpr 2.7.3 numpy 1.20.2 numpy-groupies 0.9.13 ordered-set 4.0.2 packaging 20.9 palettable 3.3.0 pandas 1.2.3 pandocfilters 1.4.3 parso 0.8.1 patsy 0.5.1 pep517 0.10.0 pexpect 4.8.0 pickleshare 0.7.5 Pillow 8.2.0 pip 20.3.1 plotly 4.14.3 plotnine 0.8.0 pluggy 0.13.1 ply 3.11 powerline-status 2.8.2 progress 1.5 prometheus-client 0.10.1 prompt-toolkit 3.0.18 psutil 5.8.0 ptyprocess 0.7.0 PuLP 2.4 py 1.10.0 pycparser 2.20 Pygments 2.9.0 pylint 2.7.4 pyOpenSSL 20.0.1 pyparsing 2.4.7 pyrsistent 0.17.3 pytest 6.2.3 python-dateutil 2.8.1 pytoml 0.1.21 pytz 2021.1 PyYAML 5.4.1 pyzmq 22.0.3 ranger-fm 1.9.3 ratelimiter 1.2.0.post0 requests 2.25.1 resolvelib 0.5.4 retrying 1.3.3 scanpy 1.7.2 scikit-learn 0.24.2 scipy 1.6.3 scvelo 0.2.3 seaborn 0.11.1 Send2Trash 1.5.0 setuptools 56.0.0 simplejson 3.17.2 sinfo 0.3.4 six 1.15.0 smart-open 5.0.0 smmap 3.0.5 snakemake 6.3.0 sniffio 1.2.0 statsmodels 0.12.2 stdlib-list 0.8.0 stopit 1.1.2 tables 3.6.1 terminado 0.9.4 testpath 0.4.4 threadpoolctl 2.1.0 tmuxp 1.7.2 toml 0.10.2 tomlkit 0.7.0 toposort 1.6 tornado 6.1 tqdm 4.60.0 traitlets 5.0.5 umap-learn 0.4.6 urllib3 1.26.4 wcwidth 0.2.5 webencodings 0.5.1 websockets 8.1 wheel 0.36.2 widgetsnbextension 3.5.1 wrapt 1.12.1 xlrd 1.2.0 zipp 3.4.1